/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       global_event.cpp

	$Header: /game/global_event.cpp $

	$NoKeywords: $

 ************************************************************************/
// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "global_event.h"

#include "bitset_io.h"
#include "player.h"
#include "sized_int_types.h"
#include "streambuf_operators.h"

// --------------------------------------------------------------------------
// Unnamed namespace
// --------------------------------------------------------------------------

namespace
{

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	namespace player_filtered_event_details
	{

		int const k_current_map_format_version = 0;

	} // player_filtered_event_details

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	namespace timed_event_details
	{

		int const k_current_map_format_version = 0;

		inline int to_timed_event_map_format_version( int format_version )
		{
			return 0;
		}

		inline int to_player_filtered_map_format_version( int format_version )
		{
			return 0;
		}

	} // timed_event_details

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	namespace triggerable_event_details
	{

		int const k_current_map_format_version = 0;

		inline int to_base_map_format_version( int format_version )
		{
			return 0;
		}

	} // triggerable_event_details

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	namespace continuous_event_details
	{

		int const k_current_map_format_version = 0;

		inline int to_base_map_format_version( int format_version )
		{
			return 0;
		}

	} // continuous_event_details

	// --------------------------------------------------------------------------
	// --------------------------------------------------------------------------
	namespace placed_event_details
	{

		int const k_current_map_format_version = 1;

		inline int to_discrete_event_map_format_version( int format_version )
		{
			return 0;
		}

		inline int to_player_filtered_map_format_version( int format_version )
		{
			return 0;
		}

	} // placed_event_details

} // Unnamed namespace

// --------------------------------------------------------------------------
// t_global_player_filtered_event members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_player_filtered_event::read(
	std::streambuf &	stream,
	int					version )
{
	m_player_color_mask = get_bitset< k_active_player_color_count >( stream );
	m_run_for_human_players = get< t_int8 >( stream ) != 0;
	m_run_for_computer_players = get< t_int8 >( stream ) != 0;

	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_player_filtered_event::read_from_map(
	std::streambuf &	stream,
	int					format_version )
{
	assert(		format_version >= 0
			&&	format_version <= player_filtered_event_details::k_current_map_format_version );

	m_player_color_mask = get_bitset< k_active_player_color_count >( stream );

	std::bitset< 2 > player_type_mask = get_bitset< 2 >( stream );
	m_run_for_human_players = player_type_mask[ 0 ];
	m_run_for_computer_players = player_type_mask[ 1 ];

	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_player_filtered_event::write( std::streambuf & stream ) const
{
	put_bitset( stream, m_player_color_mask );
	put< t_int8 >( stream, m_run_for_human_players );
	put< t_int8 >( stream, m_run_for_computer_players );

	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_player_filtered_event::ownership_test(t_player const* player) const
{
	assert(player);

	if (player->is_computer()) {
		if (!m_run_for_computer_players)
			return false;
	} else
		if (!m_run_for_human_players)
			return false;
	
	return m_player_color_mask.test(player->get_color());
}

// --------------------------------------------------------------------------
// t_global_timed_event members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_timed_event::read(
	std::streambuf &	stream,
	int					version )
{
	return		t_timed_event::read( stream, version )
			&&	t_global_player_filtered_event::read( stream, version );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_timed_event::read_from_map( std::streambuf & stream )
{
	using namespace timed_event_details;

	int format_version = get< t_uint16 >( stream );
	if ( format_version < 0 || format_version > k_current_map_format_version )
		return false;

	return		t_timed_event::read_from_map(
					stream,
					to_timed_event_map_format_version( format_version ) )
			&&	t_global_player_filtered_event::read_from_map(
					stream,
					to_player_filtered_map_format_version( format_version ) );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_timed_event::write( std::streambuf & stream ) const
{
	return		t_timed_event::write( stream )
			&&	t_global_player_filtered_event::write( stream );
}

// --------------------------------------------------------------------------
// t_global_triggerable_event members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_triggerable_event::read_from_map( std::streambuf & stream )
{
	using namespace triggerable_event_details;

	int format_version = get< t_uint16 >( stream );
	if ( format_version < 0 || format_version > k_current_map_format_version )
		return false;

	return t_triggerable_event::read_from_map( stream, to_base_map_format_version( format_version ) );
}

// --------------------------------------------------------------------------
// t_global_continuous_event members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_continuous_event::read_from_map( std::streambuf & stream )
{
	using namespace continuous_event_details;

	int format_version = get< t_uint16 >( stream );
	if ( format_version < 0 || format_version > k_current_map_format_version )
		return false;

	return t_continuous_event::read_from_map( stream, to_base_map_format_version( format_version ) );
}

// --------------------------------------------------------------------------
// t_global_placed_event members
// --------------------------------------------------------------------------


// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_placed_event::read(
	std::streambuf &	stream,
	int					version )
{
	return		t_discrete_event::read( stream, version )
			&&	( version < 2 || t_global_player_filtered_event::read( stream, version ) )
			&&	read_string16( stream, m_name );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_placed_event::read_from_map( std::streambuf & stream )
{
	using namespace placed_event_details;

	int format_version = get< t_uint16 >( stream );
	if ( format_version < 0 || format_version > k_current_map_format_version )
		return false;

	if (	!t_discrete_event::read_from_map(
				stream,
				to_discrete_event_map_format_version( format_version ) ) )
		return false;

	if (	format_version >= 1
		&&	!t_global_player_filtered_event::read_from_map(
				stream,
				to_player_filtered_map_format_version( format_version ) ) )
		return false;

	return read_string16( stream, m_name );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_global_placed_event::write( std::streambuf & stream ) const
{
	return		t_discrete_event::write( stream )
			&&	t_global_player_filtered_event::write( stream )
			&&	write_string16( stream, m_name );
}
